#include"stdTcpService.h"
#include<iostream>
 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>
#include<unistd.h>
#include<cstring>
#include<arpa/inet.h>
#include <ctype.h>
#include<stdio.h>
#define PORT 8080



void StdTcpService::setListen(int port)
{
     /*创建通信文件描述符*/
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        perror("create error:");
        _exit(-1);

    }
    //设置地址复用
    int optval=1;//1开启
    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
    if(ret==-1){
        perror("set opt error:");
        _exit(-1);
    }

    /*绑定服务器的ip和端口信息*/
    sockaddr_in localAddress;
    /*清除脏数据*/
    memset(&localAddress,0,sizeof(localAddress));
    /*地址族*///IPV4
    localAddress.sin_family=AF_INET;  
    //端口
    localAddress.sin_port=htons(PORT);
    // 绑定到所有可用的网络接口，允许接收任意 IP 地址的连接
    localAddress.sin_addr.s_addr=INADDR_ANY;
    ret=bind(sockfd,(const sockaddr*)&localAddress,sizeof(localAddress));
    if(ret==-1)
    {
        perror("bind error");
        _exit(-1);
    }
    //监听************
    ret=listen(sockfd,10);
    if(ret==-1){
        perror("listen error:");
        _exit(-1);
    }
    /*维护socket句柄属性*/
    m_sockfd=sockfd;
    /*维护端口属性*/
    m_port=port;

}



std::shared_ptr<StdTcpSocket> StdTcpService::getClientSock()
{
       int connfd=accept(m_sockfd,NULL,NULL);
        if(connfd==-1)
        {
            perror("accept error:");
            _exit(-1);
        }
       std::cout<<"有新客户端连接,connfd"<<connfd<<std::endl;

    /*通信类*/
     auto ptr = std::make_shared<StdTcpSocket>();
     ptr->setConnfdAttr(connfd);
     return ptr;


}


  /*连接服务器*/
    bool StdTcpSocket::conectToServer(const char*ip,int port)
    {
            /*创建通信文件描述符*/
        int sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(sockfd==-1)
        {
            perror("socket create error:");
            return false;

        }
        /*链接服务器*/
        sockaddr_in serverAddress;
        /*地址族 IPV4*/
        serverAddress.sin_family=AF_INET;
        /*端口*/
        serverAddress.sin_port=htons(PORT);
        /*服务器Ip地址*/
        const char *serverIp=ip;
        //主机字节序转换成网络字节序
        inet_pton(AF_INET,serverIp,&(serverAddress.sin_addr.s_addr));

        /*链接服务器*/
        int ret=connect(sockfd,(const sockaddr *)&serverAddress,sizeof(serverAddress));
        if(ret==-1)
        {
            perror("connect error:");
            return false;
        }
        /*维护套接字句柄*/
        m_connfd=sockfd;
        return true;


    }
    /*发送数据*/
    int StdTcpSocket::sendMessage(const void *sendMsg,size_t size)
    {
        /*发送数据的大小*/
        write(m_connfd,&size,sizeof(size_t));
        /*发送数据本身*/
        size_t writeBytes=write(m_connfd,sendMsg,size);
        return writeBytes;
    }
    /*发送数据2*/
    int StdTcpSocket::sendMessage(const std::string &sendMsg)
    {
        return  sendMessage(sendMsg.c_str(),sendMsg.size());
    }
    /*接收数据*/
    int StdTcpSocket::receMessage(void *buf,size_t size)
    {
            return 0;
    }
    /*接受数据2*/
    int StdTcpSocket::receMessage(std::string& receMessage)
    {
        /*1.先得到数据包的大小*/
        size_t datasize=0;
        size_t readBytes=read(m_connfd,&datasize,sizeof(size_t));



        /*2.再获得数据本身*/
        char *msg=new char[datasize+1];
        if(msg==nullptr)
        {
            /*todo*/
        }
        /*清除脏数据*/
        memset(msg,0,sizeof(char)*(datasize+1));
        size_t totalReceived=0;
        /*为了避免因为网络波动而少读的问题*/
        while(totalReceived<datasize)
        {
            readBytes=read(m_connfd,msg+totalReceived,datasize-totalReceived);
            totalReceived+=readBytes;
        }
        /*赋值*/
        receMessage=msg;
        /*释放堆空间*/
        delete[]msg;
        return datasize;
    }
    /*设置通信句柄*/
    void StdTcpSocket::setConnfdAttr(int connfd)
    {
        this->m_connfd=connfd;
    }
